package com.itheima.user.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.common.properties.WeChatProperties;
import com.itheima.model.common.dtos.PageResponseResult;
import com.itheima.model.common.dtos.ResponseResult;
import com.itheima.model.common.enums.AppHttpCodeEnum;
import com.itheima.model.user.dtos.LoginDto;
import com.itheima.model.user.dtos.UserQueryDto;
import com.itheima.model.user.pojos.User;
import com.itheima.model.user.vos.AuthorVo;
import com.itheima.model.user.vos.LoginVo;
import com.itheima.user.mapper.UserMapper;
import com.itheima.user.service.UserService;
import com.itheima.utils.common.HttpClientUtil;
import com.itheima.utils.common.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    // 微信登录接口配置
    public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private WeChatProperties weChatProperties;

    /**
     * 用户登录
     * @param dto
     * @return
     */
    @Override
    public ResponseResult login(LoginDto dto) {
        if(dto==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        String openId = getOpenId(dto.getCode());
        if (openId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_FAIL);
        }

        User user = getOne(Wrappers.<User>lambdaQuery().eq(User::getOpenId, openId));
        if (user == null) {
            user = User.builder()
                    .openId(openId)
                    .avatar(dto.getAvatar())
                    .nickname(dto.getNickname())
                    .status(User.ENABLE)
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build();
            userMapper.insert(user);
        }
        String token= JwtUtil.getToken(user.getId().longValue());
        LoginVo vo = new LoginVo();
        BeanUtils.copyProperties(user, vo);
        vo.setToken(token);
        return ResponseResult.okResult(vo);
    }

    /**
     * 获取作者信息
     * @param authorId
     * @return
     */
    @Override
    @Cacheable(value = "author",key = "#authorId")
    public ResponseResult getAuthorVo(Integer authorId) {
        User user = getOne(Wrappers.<User>lambdaQuery().eq(User::getId, authorId));
        if(user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        AuthorVo vo = new AuthorVo();
        BeanUtils.copyProperties(user, vo);
        //数据脱敏
        vo.setOpenId(null);
        vo.setCreateTime(null);
        vo.setUpdateTime(null);
        return ResponseResult.okResult(vo);
    }

    /**
     * 分页查询用户列表（使用 MyBatis Plus 的 page 方法）
     */
    @Override
    public ResponseResult listUsers(UserQueryDto dto) {
        log.info("查询用户列表: {}", dto);
        
        try {
            // 校验并设置默认分页参数
            dto.checkParam();
            
            // 构建查询条件
            LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>lambdaQuery();
            
            // 昵称模糊查询
            if (dto.getNickname() != null && !dto.getNickname().trim().isEmpty()) {
                queryWrapper.like(User::getNickname, dto.getNickname());
            }
            
            // 手机号模糊查询
            if (dto.getPhone() != null && !dto.getPhone().trim().isEmpty()) {
                queryWrapper.like(User::getPhone, dto.getPhone());
            }
            
            // 状态精确查询
            if (dto.getStatus() != null) {
                queryWrapper.eq(User::getStatus, dto.getStatus());
            }
            
            // 按创建时间倒序
            queryWrapper.orderByDesc(User::getCreateTime);
            
            // 使用 MyBatis Plus 的 page 方法
            IPage<User> pageObj = new Page<>(dto.getPage(), dto.getSize());
            IPage<User> result = page(pageObj, queryWrapper);
            
            PageResponseResult pageResponse = new PageResponseResult(dto.getPage(), dto.getSize(), (int) result.getTotal());
            pageResponse.setData(result.getRecords());
            
            return pageResponse;
        } catch (Exception e) {
            log.error("查询用户列表失败", e);
            return ResponseResult.errorResult(500, "查询用户列表失败：" + e.getMessage());
        }
    }

    /**
     * 根据ID查询用户详情（使用 MyBatis Plus 的 getById 方法）
     */
    @Override
    public ResponseResult getUserById(Integer id) {
        log.info("查询用户详情: userId={}", id);
        
        try {
            // 使用 MyBatis Plus 的 getById 方法
            User user = getById(id);
            if (user == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
            }
            return ResponseResult.okResult(user);
        } catch (Exception e) {
            log.error("查询用户详情失败, userId={}", id, e);
            return ResponseResult.errorResult(500, "查询用户详情失败：" + e.getMessage());
        }
    }

    /**
     * 更新用户状态（使用 MyBatis Plus 的 updateById 方法）
     */
    @Override
    public ResponseResult updateUserStatus(Integer id, UserQueryDto dto) {
        log.info("更新用户状态: userId={}, dto={}", id, dto);
        
        try {
            if (dto.getStatus() == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "status参数不能为空");
            }
            
            // 使用 MyBatis Plus 的 getById 方法
            User user = getById(id);
            if (user == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
            }
            
            user.setStatus(dto.getStatus());
            user.setUpdateTime(new Date());
            
            // 使用 MyBatis Plus 的 updateById 方法
            boolean success = updateById(user);
            
            if (success) {
                return ResponseResult.okResult("更新成功");
            } else {
                return ResponseResult.errorResult(500, "更新失败");
            }
        } catch (Exception e) {
            log.error("更新用户状态失败, userId={}", id, e);
            return ResponseResult.errorResult(500, "更新用户状态失败：" + e.getMessage());
        }
    }

    /**
     * 根据授权码获取openId
     * @param code
     * @return
     */
    private String getOpenId(String code) {
        Map<String, String> map = new HashMap<>();
        map.put("appId", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        String json = HttpClientUtil.doGet(WX_LOGIN, map);
        JSONObject jsonObject = JSON.parseObject(json);
        return jsonObject.getString("openid");
    }
}
